import { useRef, useEffect, useState, useCallback } from "react";
import { motion, AnimatePresence } from "motion/react";
import { useChatStore } from "./stores/useChatStore";
import { useAgentStore } from "./stores/useAgentStore";
import { useMcpStore } from "./stores/useMcpStore";
import { useUIStore } from "./stores/useUIStore";
import { useProviderStore } from "./stores/useProviderStore";
import { MessageList } from "./components/MessageList";
import { EnhancedChatInput } from "./components/EnhancedChatInput";
import { Sidebar } from "./components/Sidebar";
import { Header } from "./components/Header";
import { AgentManager, type Agent } from "./components/AgentManager";
import { ToolManager, type McpService } from "./components/ToolManager";
import { ExtensionsPanel } from "./components/ExtensionsPanel";
import { SettingsPanel } from "./components/SettingsPanel";
import { useHotkeys } from "./hooks/useHotkeys";
import { useStreaming } from "./hooks/useStreaming";
import apiService from "./lib/api";

// 聊天消息类型
interface ChatMessage {
	id: string;
	role: "user" | "assistant";
	content: string;
	timestamp: Date;
	status?: "sending" | "sent" | "delivered" | "error";
	reactions?: string[];
	isStreaming?: boolean;
}

function App() {
	// 状态管理
	const {
		inputText,
		chatMessages,
		chatSessions,
		currentSessionId,
		setInputText,
		setLoading,
		setChatMessages,
		addChatMessage,
		updateChatMessage,
		setCurrentSessionId,
		addChatSession,
		updateChatSession,
		removeChatSession,
	} = useChatStore();

	const {
		agents,
		selectedAgent,
		setAgents,
		addAgent,
		removeAgent,
		setSelectedAgent,
	} = useAgentStore();

	const {
		mcpServices,
		mcpTools,
		setMcpServices,
		addMcpService,
		removeMcpService,
		setMcpTools,
	} = useMcpStore();

	const { sidebarOpen, toggleSidebar } = useUIStore();

	const { availableProviders, loadProviders, isProviderFullyConfigured } =
		useProviderStore();

	// 本地状态
	const [editingMessageId, setEditingMessageId] = useState<string | null>(null);
	const [editedText, setEditedText] = useState("");
	const [isTyping, setIsTyping] = useState(false);
	const [streamingMessage, setStreamingMessage] = useState<ChatMessage | null>(
		null,
	);
	const [copiedMessageId, setCopiedMessageId] = useState<string | null>(null);
	const [isMobile, setIsMobile] = useState(false);
	const [currentView, setCurrentView] = useState<
		"chat" | "extensions" | "settings"
	>("chat");
	const [attachedFiles, setAttachedFiles] = useState<File[]>([]);

	// Refs
	const messagesEndRef = useRef<HTMLDivElement>(null);
	const inputRef = useRef<HTMLTextAreaElement | null>(null);

	// 检测是否为移动端
	useEffect(() => {
		const checkIsMobile = () => {
			setIsMobile(window.innerWidth < 768);
		};

		checkIsMobile();
		window.addEventListener("resize", checkIsMobile);

		return () => {
			window.removeEventListener("resize", checkIsMobile);
		};
	}, []);

	// 流式响应处理
	const { startStreaming, stopStreaming, isStreaming } = useStreaming({
		onChunk: (chunk) => {
			if (streamingMessage) {
				setStreamingMessage((prev) => ({
					...prev!,
					content: prev!.content + chunk,
					isStreaming: true,
				}));
			}
		},
		onComplete: (content: string) => {
			if (streamingMessage) {
				const finalMessage: ChatMessage = {
					...streamingMessage,
					content: content,
					isStreaming: false,
					status: "sent",
				};
				addChatMessage(finalMessage);
				setStreamingMessage(null);
				updateCurrentSession(content);
			}
			setLoading(false);
			setIsTyping(false);
		},
		onError: (error) => {
			console.error("Streaming error:", error);
			const errorMessage: ChatMessage = {
				id: Date.now().toString(),
				role: "assistant",
				content: "抱歉，发送消息时出现错误。请稍后重试。",
				timestamp: new Date(),
				status: "error",
			};
			addChatMessage(errorMessage);
			setStreamingMessage(null);
			setLoading(false);
			setIsTyping(false);
		},
	});

	// 键盘快捷键
	useHotkeys([
		{ key: "ctrl+k", callback: () => inputRef.current?.focus() },
		{ key: "ctrl+l", callback: () => setChatMessages([]) },
		{ key: "ctrl+n", callback: () => createNewSession() },
		{
			key: "esc",
			callback: () => {
				setEditingMessageId(null);
				setEditedText("");
			},
		},
	]);

	// 自动滚动到底部
	const scrollToBottom = useCallback(() => {
		messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
	}, []);

	useEffect(() => {
		scrollToBottom();
	}, [chatMessages, streamingMessage, scrollToBottom]);

	// 初始化数据
	useEffect(() => {
		loadAgents();
		loadMcpServices();
		loadMcpTools();
		loadProviders();
	}, []);

	// Provider Guard Logic
	useEffect(() => {
		if (availableProviders.length > 0 && selectedAgent) {
			const agentProvider = (selectedAgent as any).provider || "";
			const isConfigured = isProviderFullyConfigured(agentProvider);
			if (!isConfigured) {
				console.warn(
					`Provider '${agentProvider}' for selected agent '${selectedAgent.name}' is not configured. Redirecting to settings.`,
				);
				setCurrentView("settings");
			}
		} else if (availableProviders.length > 0 && !selectedAgent) {
			const anyProviderConfigured = availableProviders.some((p) =>
				isProviderFullyConfigured(p.name),
			);
			if (!anyProviderConfigured) {
				console.log("No providers configured. Redirecting to settings.");
				setCurrentView("settings");
			}
		}
	}, [
		availableProviders,
		selectedAgent,
		isProviderFullyConfigured,
		setCurrentView,
	]);

	// API 调用
	const loadAgents = async () => {
		try {
			const data = await apiService.getAgents();
			if (data.agents) {
				setAgents(data.agents);
			}
		} catch (error) {
			console.error("Failed to load agents:", error);
		}
	};

	const createAgent = async (agent: Partial<Agent>) => {
		try {
			const newAgent = await apiService.createAgent(agent);
			addAgent(newAgent);
			return newAgent;
		} catch (error) {
			console.error("Failed to create agent:", error);
			throw error;
		}
	};

	const deleteAgent = async (id: string) => {
		try {
			await apiService.deleteAgent(id);
			removeAgent(id);
		} catch (error) {
			console.error("Failed to delete agent:", error);
		}
	};

	const loadMcpServices = async () => {
		try {
			const data = await apiService.getMcpServices();
			if (data.services) {
				setMcpServices(data.services);
			}
		} catch (error) {
			console.info("Failed to load MCP services:", error);
		}
	};

	const loadMcpTools = async () => {
		try {
			const data = await apiService.getMcpTools();
			if (data.tools) {
				setMcpTools(data.tools);
			}
		} catch (error) {
			console.info("Failed to load MCP tools:", error);
		}
	};

	const createMcpService = async (service: Partial<McpService>) => {
		try {
			const newService = await apiService.createMcpService(service);
			addMcpService(newService);
			return newService;
		} catch (error) {
			console.error("Failed to create MCP service:", error);
			throw error;
		}
	};

	const deleteMcpService = async (id: string) => {
		try {
			await apiService.deleteMcpService(id);
			removeMcpService(id);
		} catch (error) {
			console.error("Failed to delete MCP service:", error);
		}
	};

	// 会话管理
	const createNewSession = () => {
		const newSession = {
			id: Date.now().toString(),
			title: "新会话",
			lastMessage: "",
			timestamp: new Date(),
			messageCount: 0,
			agentName: selectedAgent?.name,
		};
		addChatSession(newSession);
		setCurrentSessionId(newSession.id);
		setChatMessages([]);
		return newSession.id;
	};

	const updateCurrentSession = (lastMessage: string) => {
		if (!currentSessionId) return;

		updateChatSession(currentSessionId, {
			lastMessage,
			timestamp: new Date(),
			messageCount: chatMessages.length + 1,
			title:
				chatSessions.find((s) => s.id === currentSessionId)?.title === "新会话"
					? lastMessage.slice(0, 30) + "..."
					: chatSessions.find((s) => s.id === currentSessionId)?.title,
		});
	};

	// 消息操作
	const handleSendMessage = async (message: string, agentId?: string) => {
		if (!message.trim()) return;

		const agentProvider = (selectedAgent as any)?.provider || "";
		if (!selectedAgent || !isProviderFullyConfigured(agentProvider)) {
			console.error("请先在设置中配置所选代理的提供商。");
			setCurrentView("settings");
			return;
		}

		if (!currentSessionId) {
			createNewSession();
		}

		setLoading(true);
		setIsTyping(true);

		const userMessage: ChatMessage = {
			id: Date.now().toString(),
			role: "user",
			content: message,
			timestamp: new Date(),
			status: "sent",
		};
		addChatMessage(userMessage);

		const assistantMessage: ChatMessage = {
			id: (Date.now() + 1).toString(),
			role: "assistant",
			content: "",
			timestamp: new Date(),
			isStreaming: true,
		};
		setStreamingMessage(assistantMessage);

		setInputText("");

		try {
			if (selectedAgent?.name) {
				await startStreaming({
					agent_id: agentId || selectedAgent?.id,
					prompt: message,
					history: chatMessages.slice(-10),
				});
			} else {
				const response = await apiService.chat(
					selectedAgent?.name || "default",
					{
						prompt: message,
						history: chatMessages.slice(-10),
					},
				);

				if (streamingMessage) {
					const finalMessage: ChatMessage = {
						...streamingMessage,
						content: response.content || response.message,
						isStreaming: false,
						status: "sent",
					};
					addChatMessage(finalMessage);
					setStreamingMessage(null);
					updateCurrentSession(response.content || response.message);
				}
				setLoading(false);
				setIsTyping(false);
			}
		} catch (error) {
			console.error("Failed to send chat message:", error);
			stopStreaming();

			const errorMessage: ChatMessage = {
				id: Date.now().toString(),
				role: "assistant",
				content: "抱歉，发送消息时出现错误。请稍后重试。",
				timestamp: new Date(),
				status: "error",
			};
			addChatMessage(errorMessage);
			setStreamingMessage(null);
			setLoading(false);
			setIsTyping(false);
		}
	};

	const handleCopyMessage = async (text: string, messageId: string) => {
		try {
			await navigator.clipboard.writeText(text);
			setCopiedMessageId(messageId);
			setTimeout(() => setCopiedMessageId(null), 2000);
		} catch (error) {
			console.error("Failed to copy message:", error);
		}
	};

	const handleEditMessage = (messageId: string) => {
		const message = chatMessages.find((m) => m.id === messageId);
		if (message) {
			setEditingMessageId(messageId);
			setEditedText(message.content);
		}
	};

	const handleSaveEditedMessage = (messageId: string) => {
		updateChatMessage(messageId, { content: editedText });
		setEditingMessageId(null);
		setEditedText("");
	};

	const handleRegenerateMessage = async (messageId: string) => {
		const message = chatMessages.find((m) => m.id === messageId);
		if (message?.role === "assistant") {
			const userMessageIndex =
				chatMessages.findIndex((m) => m.id === messageId) - 1;
			const userMessage = chatMessages[userMessageIndex];

			if (userMessage) {
				const updatedMessages = chatMessages.filter((m) => m.id !== messageId);
				setChatMessages(updatedMessages);
				await handleSendMessage(userMessage.content);
			}
		}
	};

	const handleAddReaction = (messageId: string, reaction: string) => {
		updateChatMessage(messageId, {
			reactions: [
				...(chatMessages.find((m) => m.id === messageId)?.reactions || []),
				reaction,
			],
		});
	};

	// 计算所有消息（包括流式消息）
	const allMessages = streamingMessage
		? [...chatMessages, streamingMessage]
		: chatMessages;

	return (
		<div className="h-screen bg-gradient-to-br from-slate-50 via-white to-slate-100 dark:from-slate-950 dark:via-slate-900 dark:to-slate-800 flex overflow-hidden relative">
			{/* 背景装饰 */}
			<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-blue-50/20 via-transparent to-purple-50/20 dark:from-blue-950/20 dark:via-transparent dark:to-purple-950/20 pointer-events-none" />

			{/* 侧边栏 */}
			<AnimatePresence mode="wait">
				{(sidebarOpen || !isMobile) && (
					<motion.div
						initial={{ x: -320, opacity: 0 }}
						animate={{ x: 0, opacity: 1 }}
						exit={{ x: -320, opacity: 0 }}
						transition={{ type: "spring", damping: 25, stiffness: 200 }}
						className={`${isMobile ? "absolute z-50" : "relative"} h-full`}
					>
						<Sidebar
							isOpen={sidebarOpen}
							onToggle={toggleSidebar}
							sessions={chatSessions}
							currentSessionId={currentSessionId}
							onSessionSelect={(sessionId) => {
								setCurrentSessionId(sessionId);
								if (isMobile) toggleSidebar();
							}}
							onNewSession={createNewSession}
							onDeleteSession={removeChatSession}
							onRenameSession={(sessionId, newTitle) => {
								updateChatSession(sessionId, { title: newTitle });
							}}
						/>
					</motion.div>
				)}
			</AnimatePresence>

			{/* 移动端遮罩 */}
			{isMobile && sidebarOpen && (
				<motion.div
					initial={{ opacity: 0 }}
					animate={{ opacity: 1 }}
					exit={{ opacity: 0 }}
					onClick={toggleSidebar}
					className="absolute inset-0 bg-black/20 backdrop-blur-sm z-40"
				/>
			)}

			{/* 主内容区域 */}
			<motion.div
				className="flex-1 flex flex-col h-full relative z-10"
				initial={{ opacity: 0, y: 20 }}
				animate={{ opacity: 1, y: 0 }}
				transition={{ delay: 0.1 }}
			>
				{/* 顶部导航栏 */}
				<Header
					selectedAgent={selectedAgent}
					onAgentSelect={setSelectedAgent}
					onMenuClick={toggleSidebar}
					onExtensionsClick={() => setCurrentView("extensions")}
					onSettingsClick={() => setCurrentView("settings")}
				/>

				{/* 主视图区域 */}
				<AnimatePresence mode="wait">
					{currentView === "chat" && (
						<motion.div
							key="chat"
							initial={{ opacity: 0, scale: 0.98 }}
							animate={{ opacity: 1, scale: 1 }}
							exit={{ opacity: 0, scale: 0.98 }}
							transition={{ duration: 0.2 }}
							className="flex-1 flex flex-col overflow-hidden"
						>
							{/* 消息列表 */}
							<div className="flex-1 overflow-hidden relative">
								<div className="absolute inset-0 bg-gradient-to-b from-transparent via-white/5 to-transparent dark:via-slate-900/5 pointer-events-none" />
								<MessageList
									messages={allMessages.map((msg) => ({
										id: msg.id,
										text: msg.content,
										sender: msg.role,
										timestamp: msg.timestamp,
										status: msg.status,
										reactions: msg.reactions,
										isStreaming: msg.isStreaming,
									}))}
									editingMessageId={editingMessageId}
									editedText={editedText}
									onCopyMessage={(text, messageId) =>
										handleCopyMessage(text, messageId)
									}
									onEditMessage={handleEditMessage}
									onSaveEditedMessage={handleSaveEditedMessage}
									onCancelEdit={() => {
										setEditingMessageId(null);
										setEditedText("");
									}}
									onAddReaction={handleAddReaction}
									onEditChange={setEditedText}
									onRegenerateMessage={handleRegenerateMessage}
									currentAgentName={selectedAgent?.name}
									currentAgentDescription={selectedAgent?.description}
									copiedMessageId={copiedMessageId}
								/>
								<div ref={messagesEndRef} />
							</div>

							{/* 输入区域 */}
							<motion.div
								className="border-t border-white/20 dark:border-slate-700/50 bg-white/80 dark:bg-slate-900/80 backdrop-blur-xl"
								initial={{ y: 50, opacity: 0 }}
								animate={{ y: 0, opacity: 1 }}
								transition={{ delay: 0.2 }}
							>
								<EnhancedChatInput
									inputText={inputText}
									isTyping={isTyping || isStreaming}
									onInputChange={setInputText}
									onSubmit={(e) => {
										e.preventDefault();
										handleSendMessage(inputText);
									}}
									inputRef={inputRef as React.RefObject<HTMLTextAreaElement>}
									onStopGeneration={stopStreaming}
									onFileAttach={(files) => {
										setAttachedFiles((prev) => [...prev, ...files]);
									}}
									onVoiceRecord={(isRecording) => {
										console.log("Voice recording:", isRecording);
									}}
									attachedFiles={attachedFiles}
									onRemoveFile={(index) => {
										setAttachedFiles((prev) =>
											prev.filter((_, i) => i !== index),
										);
									}}
									placeholder="输入消息... 支持拖拽文件、语音输入和表情符号"
								/>
							</motion.div>
						</motion.div>
					)}

					{/* 扩展管理视图 */}
					{currentView === "extensions" && (
						<motion.div
							key="extensions"
							initial={{ opacity: 0, x: 20 }}
							animate={{ opacity: 1, x: 0 }}
							exit={{ opacity: 0, x: -20 }}
							transition={{ duration: 0.3 }}
							className="flex-1"
						>
							<ExtensionsPanel
								isOpen={true}
								onClose={() => setCurrentView("chat")}
								extensions={mcpServices.map((service) => ({
									id: service.id,
									name: service.name,
									type: "stdio" as const,
									description: `MCP Service: ${service.command}`,
									enabled: true,
									cmd: service.command,
									args: service.args,
									envs: service.env,
									status: "connected" as const,
								}))}
								tools={mcpTools}
								onExtensionCreate={async (extension) => {
									await createMcpService({
										name: extension.name!,
										command: extension.cmd!,
										args: extension.args,
										env: extension.envs,
									});
								}}
								onExtensionUpdate={async (id, updates) => {
									console.log("Update extension:", id, updates);
								}}
								onExtensionDelete={deleteMcpService}
								onExtensionToggle={async (id, enabled) => {
									console.log("Toggle extension:", id, enabled);
								}}
								onToolExecute={async (toolName, params) => {
									try {
										const response = await fetch(
											`/api/tools/${toolName}/execute`,
											{
												method: "POST",
												headers: { "Content-Type": "application/json" },
												body: JSON.stringify(params),
											},
										);
										return response.json();
									} catch (error) {
										return { error: (error as Error).message };
									}
								}}
							/>
						</motion.div>
					)}

					{/* 设置视图 */}
					{currentView === "settings" && (
						<motion.div
							key="settings"
							initial={{ opacity: 0, x: 20 }}
							animate={{ opacity: 1, x: 0 }}
							exit={{ opacity: 0, x: -20 }}
							transition={{ duration: 0.3 }}
							className="flex-1"
						>
							<SettingsPanel
								isOpen={true}
								onClose={() => setCurrentView("chat")}
								initialTab={
									currentView === "settings" ? "providers" : undefined
								}
							/>
						</motion.div>
					)}
				</AnimatePresence>
			</motion.div>

			{/* 浮动工具栏 - 桌面端 */}
			{!isMobile && currentView === "chat" && (
				<motion.div
					className="fixed top-4 right-4 flex gap-2 z-40 opacity-0"
					initial={{ opacity: 0, y: -20 }}
					animate={{ opacity: 0, y: 0 }}
					transition={{ delay: 0.3 }}
				>
					<AgentManager
						agents={agents}
						selectedAgent={selectedAgent}
						onAgentSelect={setSelectedAgent}
						onAgentCreate={createAgent}
						onAgentDelete={deleteAgent}
					/>

					<ToolManager
						mcpServices={mcpServices}
						mcpTools={mcpTools}
						onServiceCreate={createMcpService}
						onServiceDelete={deleteMcpService}
					/>
				</motion.div>
			)}
		</div>
	);
}

export default App;

